<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    .box{width: 350px;position: relative;margin: 50px;}
    .m_box{width: 350px;height: 350px;position: relative;}
    .m_box span{position: absolute;left:0;top:0;background: rgba(255,0,0,0.5);display: none;}

    .m_box em{position: absolute;z-index: 1;left:0;right:0;top:0;bottom:0;}

    .b_box{width: 350px;height: 350px;position: absolute;top: 0;left:360px;overflow: hidden;display: none;}
    .b_box img{position: absolute;left:0;top:0;}

    .s_box{display: flex;margin: 10px 0;}
    .s_box img{margin: 0 5px;border: solid 2px transparent;display: block;}
  </style>
</head>
<body>
  <div class="box">
    <div class="m_box">
      <img src="../imgs/m0.jpg" alt="">
      <span></span>
      <em></em>
    </div>
    <div class="s_box">
      <img src="../imgs/s0.jpg" alt="">
      <img src="../imgs/s1.jpg" alt="">
      <img src="../imgs/s2.jpg" alt="">
    </div>
    <div class="b_box">
      <img src="../imgs/l0.jpg" alt="">
    </div>
  </div>
</body>
<script>

  function BigImg( {mBox, mSpan, bBox, bImg, sImgs, data, mImg, index} ){
    this.mBox = mBox;
    this.mSpan = mSpan;
    this.bBox = bBox;
    this.bImg = bImg;
    
    this.sImgs = sImgs;
    this.mImg = mImg;
    this.data = data;
    this.index = index;
    // 根据默认索引，设置小图的高亮，及中图和大图信息
    this.sImgs[this.index].style.borderColor = "blue";
    this.mImg.src = this.data[this.index].middle;
    this.bImg.src = this.data[this.index].large;

    this.addEvent();
  }
  BigImg.prototype.addEvent = function(){
    const that = this;
    this.mBox.onmouseover = function(){
      that.show()
    }
    this.mBox.onmouseout = function(){
      that.hide()
    }
    this.mBox.onmousemove = function(eve){
      const e = eve || window.event;
      that.move( e );
    }
    // 遍历所有小图
    this.sImgs.forEach((val, idx)=>{
      // 绑定事件
      val.onclick = function(){
        // 取消上一个小图的高亮
        that.sImgs[that.index].style.borderColor = "transparent";
        // 给当前点击的小图添加高亮
        this.style.borderColor = "blue";
        // 将当前点击小图的索引对应的数据中的中图和大图设置到指定位置
        that.mImg.src = that.data[idx].middle;
        that.bImg.src = that.data[idx].large;
        // 将本次点击的小图索引设置为下次要清除的索引
        that.index = idx;
      }
    })
  }
  BigImg.prototype.show = function(){
    this.mSpan.style.display = "block";
    this.bBox.style.display = "block";

    this.bBoxW = this.bBox.offsetWidth;
    this.bBoxH = this.bBox.offsetHeight;
    this.bImgW = this.bImg.offsetWidth;
    this.bImgH = this.bImg.offsetHeight;
    this.mBoxW = this.mBox.offsetWidth;
    this.mBoxH = this.mBox.offsetHeight;
    this.mSpanW = this.bBoxW / this.bImgW * this.mBoxW;
    this.mSpanH = this.bBoxH / this.bImgH * this.mBoxH;
    this.mSpan.style.width = this.mSpanW + "px";
    this.mSpan.style.height = this.mSpanH + "px";
  }
  BigImg.prototype.hide = function(){
    this.mSpan.style.display = "none";
    this.bBox.style.display = "none";
  }
  BigImg.prototype.move = function(e){
    let l = e.offsetX - this.mSpanW / 2;
    let t = e.offsetY - this.mSpanH / 2;
    if(l < 0) l = 0;
    if(t < 0) t = 0;
    if( l > this.mBoxW - this.mSpanW ){
      l = this.mBoxW - this.mSpanW
    }
    if( t > this.mBoxH - this.mSpanH ){
      t = this.mBoxH - this.mSpanH
    }
    this.mSpan.style.left = l + "px";
    this.mSpan.style.top = t + "px";
    const x = l / (this.mBoxW - this.mSpanW);
    const y = t / (this.mBoxH - this.mSpanH);
    this.bImg.style.left = -(this.bImgW - this.bBoxW) * x + "px"; 
    this.bImg.style.top = -(this.bImgH - this.bBoxH) * y + "px"; 
  }



  new BigImg({
    mBox: document.querySelector(".m_box"),
    mSpan: document.querySelector(".m_box span"),
    bBox: document.querySelector(".b_box"),
    bImg: document.querySelector(".b_box img"),
    // 左侧容器内的图片（中图）
    mImg: document.querySelector(".m_box img"),
    // 下方容器中所有的按钮（小图）
    sImgs: document.querySelectorAll(".s_box img"),
    // 多张图片时，需要有默认索引
    index: 0,
    // 多张图片信息
    data: [{
      small:"../imgs/s0.jpg",
      middle:"../imgs/m0.jpg",
      large:"../imgs/l0.jpg"
    },{
      small:"../imgs/s1.jpg",
      middle:"../imgs/m1.jpg",
      large:"../imgs/l1.jpg"
    },{
      small:"../imgs/s2.jpg",
      middle:"../imgs/m2.jpg",
      large:"../imgs/l2.jpg"
    }]
  })



  
</script>
</html>